Skip to content

Add scaled usage metrics to per-Dandiset table - #241

Open
CodyCBakerPhD wants to merge 12 commits into
mainfrom
claude/dandiset-scaled-metrics-xia39y
Open

Add scaled usage metrics to per-Dandiset table#241
CodyCBakerPhD wants to merge 12 commits into
mainfrom
claude/dandiset-scaled-metrics-xia39y

Conversation

@CodyCBakerPhD

Copy link
Copy Markdown
Collaborator

Summary

This PR adds four new "scaled" usage metrics to the per-Dandiset table that normalize raw usage statistics by the actual content each Dandiset holds. These metrics provide better insight into usage patterns relative to dataset size.

Key Changes

  • New utility functions (scaled_metric, format_ratio): Calculate and format per-unit metrics with appropriate precision based on magnitude
  • Gzip decompression support: Added decode_maybe_gzipped_response and fetch_maybe_gzipped_text to handle client-side decompression of gzipped derivative files served without Content-Encoding headers
  • JSONL parsing for numeric data: Added parse_dandiset_numbers_jsonl to parse Dandiset ID → number mappings (complementing the existing title parser)
  • New data sources: Integrated two gzipped JSONL files containing asset counts and total sizes per Dandiset as denominators for scaled metrics
  • Four new table columns:
    • "Bytes / Size": bytes sent per byte stored
    • "Views / Asset": views per asset
    • "Downloads / Asset": downloads per asset
    • "Requests / Asset": requests per asset
  • Improved sorting: Modified render_sortable_table to handle NaN values (representing unavailable metrics) by always sorting them to the bottom, regardless of sort direction
  • Comprehensive test coverage: Added unit tests for all new functions and integration tests for the visual rendering with missing metric values

Implementation Details

  • Gzip detection uses magic number checking (0x1f 0x8b) to distinguish between pre-decompressed and still-compressed responses
  • Uses the DecompressionStream API for efficient streaming decompression of large files
  • Scaled metrics return NaN for undefined ratios (missing data, zero denominators, non-finite values), which render as "--" in the UI
  • Ratio formatting adapts precision to magnitude: whole numbers with separators for ≥100, two decimals for 1-100, two significant digits for <1
  • Data loading failures for asset counts and sizes are logged but don't block page rendering (metrics gracefully degrade to "--")

https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts

Normalise the raw per-Dandiset usage numbers by how much content each
Dandiset actually holds, adding four columns to the "Usage per Dandiset"
table: "Bytes / Size" (bytes sent per byte stored), "Views / Asset",
"Downloads / Asset" and "Requests / Asset".

The denominators come from two new data sources fetched from the GitHub
raw CDN, dandi-cache/dandiset-id-to-number-of-assets and
dandi-cache/dandiset-id-to-total-size.  Both are gzipped JSONL served
without a Content-Encoding header, so they are inflated client-side via
DecompressionStream.  Either fetch failing only leaves the scaled
columns empty; the rest of the page still renders.

A ratio with an unknown or zero denominator ('undetermined', and the
handful of Dandisets absent from the derivatives) renders as "--" and
sorts to the bottom of the table in both directions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
@CodyCBakerPhD CodyCBakerPhD self-assigned this Aug 10, 2026
@CodyCBakerPhD
CodyCBakerPhD marked this pull request as ready for review August 10, 2026 20:43
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://dandi.github.io/usage-page/pr-preview/pr-241/

Built to branch gh-pages at 2026-08-10 21:57 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 19.23077% with 42 lines in your changes missing coverage. Please review.
✅ Project coverage is 17.82%. Comparing base (2dfef1b) to head (b1b52f8).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/plots.ts 0.00% 42 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #241      +/-   ##
==========================================
+ Coverage   14.04%   17.82%   +3.78%     
==========================================
  Files           4        4              
  Lines        1289     1447     +158     
  Branches      325      371      +46     
==========================================
+ Hits          181      258      +77     
- Misses       1106     1184      +78     
- Partials        2        5       +3     
Flag Coverage Δ
unit 17.82% <19.23%> (+3.78%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/plot-helpers.ts 96.31% <ø> (-1.31%) ⬇️
src/utils.ts 100.00% <100.00%> (ø)
src/plots.ts 0.00% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

claude added 11 commits August 10, 2026 20:46
Fix "normalising" -> "normalizing" in the changelog entry for the scaled
metrics, and write the convention down in AGENTS.md so it is not just
tribal knowledge.

CLAUDE.md is a symlink to AGENTS.md rather than a second copy, so both
filenames resolve to one set of instructions (matching how LICENSE
already symlinks into LICENSES/).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Put the four scaled columns ahead of the raw metrics they are derived
from, and rename those to "Total Bytes", "Total Views", "Total
Downloads" and "Total Requests" so the two groups read distinctly.

Widen the per-Dandiset table's window (1100px -> up to 1600px, still
capped by the available width) so all ten columns fit on a wide screen
instead of scrolling horizontally.

Columns gained an optional `default_sort` flag, set on "Total Bytes":
the table sorts by the first numeric column by default, which would
otherwise have moved to "Bytes / Size" and left the table ordered
differently from the plot beside it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Replace the CLAUDE.md -> AGENTS.md symlink with a single real CLAUDE.md
holding the instructions, so there is one file rather than two names for
it. Nothing outside the changelog referenced AGENTS.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Three additions to the per-Dandiset table:

- "Total Size" and "Total Assets" columns at the end, so the
  denominators behind the scaled metrics are visible next to them. Both
  read "--" for Dandisets missing from the content derivatives.
- An "Ignore testing dataset" checkbox that drops Dandisets 000027,
  000126 and 000717, whose usage is dominated by automated testing of
  the archive. It is remembered in the URL, applies to the table (and
  its download) rather than the plot, and is only shown in the table
  view of the archive-wide selection, the one place it means anything.
- The table now uses the full page width rather than the 1100px cap the
  other tables keep, so all twelve columns fit on a wide screen. The
  table is `width: fit-content`, so this is a ceiling, not a stretch.

The "Data" menu's "Download raw file" becomes "Download table": the
source file no longer contains what the table shows, so the download is
now built from the table itself -- same columns, same formatting, same
sort order in effect. The source file is still reachable via "View file
on GitHub".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
… sort

The setting belongs with the section's other settings, so move "Ignore
testing datasets" (plural, tooltip "Hide datasets used for testing
purposes") into the per-Dandiset gear-wheel panel and stop disabling
that gear in table view -- it was disabled because everything in it was
plot-only, which is no longer true. Both entries now carry an info icon
naming the view they apply to, and the panel is titled "Settings".

Re-rendering a table also no longer discards the sort the user chose:
toggling the new setting (or the binary/decimal prefix) rebuilt the
table from scratch and snapped it back to the default column. The sort
is now remembered per container element and column set, so it survives a
re-render with new rows while a genuinely different table still starts
from its own default.

setSettingsBtnDisabled had no callers left and is removed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Add 000068, 000144, 000299, 000411 and 000470, and split the list onto
one ID per line now that it no longer fits comfortably on one.

The unit tests now derive their fixture from the list and check its
shape (six-digit IDs, no duplicates, in order) instead of restating it,
and the changelog points at the constant rather than enumerating it, so
adding an ID is a one-line change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ym6LaKiE7zjkPMfzKMzts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants